package com.nameless.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.nameless.dao.MenuMapper;
import com.nameless.dao.UserMapper;
import com.nameless.entity.Menu;
import com.nameless.entity.Users;
import com.nameless.service.MenuService;
import com.nameless.util.JwtUtil;
import com.nameless.util.WebUtils;
import com.nameless.vo.Result;
import com.nameless.vo.TreeSelect;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author keluoyisi
 */
@Service
@SuppressWarnings("all")
@Slf4j
public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu> implements MenuService {

    @Autowired
    private MenuMapper menuMapper;

    @Autowired
    private UserMapper userMapper;

    @Override
    public List<Menu> selectPermission(Integer userId) {
        return menuMapper.selectPermission(userId);
    }

    @Override
    public List<Menu> leftMenu() {
        String token = WebUtils.getRequest().getHeader("token");
        Map<String, Object> map = JwtUtil.getTokenChaim(token);
        String username = (String) map.get("username");

        LambdaQueryWrapper<Users> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Users::getUserName,username);
        Users users = userMapper.selectOne(wrapper);

        List<Menu> permissions = null;

        LambdaQueryWrapper<Menu> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.orderByDesc(Menu::getOrderNum);
        queryWrapper.notIn(Menu::getMenuType,"F");

        if (username.equals("admin")){
            // 获取所有权限 -- 排除 F
            permissions = baseMapper.selectList(queryWrapper);
            log.info("permiss = {}",permissions);
        }else {
            //根据用户id查询该用户具有的菜单。
            permissions = menuMapper.selectPermissionDistictF(users.getUserId());
            log.info("permiss = {}",permissions);
        }
        return firsts(permissions);
    }

    @Override
    public Result qr(Integer roleId, Integer[] menuids) {
        menuMapper.deleteByRoleId(roleId);
        menuMapper.batchPermission(roleId,menuids);
        return new Result(200,"分配成功");
    }

    @Override
    public Result findMenuByRoleId(Integer roleId) {
        //查询所有的菜单
        List<Menu> menus = menuMapper.selectAll();
        //查询所有的一级菜单
        List<Menu> firstMenus = firsts(menus);

        //根据角色id查询菜单id
        List<Integer> menuids= menuMapper.selectRoleId(roleId);
        Map<String, Object> map = new HashMap<>();
        map.put("menuids",menuids);
        map.put("menus",firstMenus);
        log.info("{}" ,map);
        return  Result.success(map);
    }

    @Override
    public List<Menu> findAllParent(Integer id) {
        LambdaQueryWrapper<Menu> dictWrapper = new LambdaQueryWrapper<>();
        dictWrapper.eq(Menu::getParentId,id);
        List<Menu> menuList = baseMapper.selectList(dictWrapper);
        for (Menu menu : menuList) {
            Integer menuId = menu.getMenuId();
            menu.setHasChildren(this.isChildren(menuId));
        }
        return menuList;
    }
    /**
     * 构建前端所需要下拉树结构
     *
     * @param menus 菜单列表
     * @return 下拉树结构列表
     */
    public List<TreeSelect> buildMenuTreeSelect(List<Menu> menus){
        List<Menu> menuTrees = buildMenuTree(menus);
        System.out.println(menuTrees);
        return menuTrees.stream().map(TreeSelect::new).collect(Collectors.toList());
    }
    /**
     * 判断id下面是否有子节点
     *
     * @param id id
     * @return boolean
     */
    private boolean isChildren(Long id) {
        QueryWrapper<Menu> wrapper = new QueryWrapper<>();
        wrapper.eq("parent_id", id);
        long count = baseMapper.selectCount(wrapper);
        return count > 0;
    }

    @Override
    public List<TreeSelect> listWithClass() {
        // 获取全部权限
        List<Menu> menuList = baseMapper.selectList(null);
        return buildMenuTreeSelect(menuList);
    }

    /**
     * 判断id下面是否有子节点
     *
     * @param id id
     * @return boolean
     */
    private boolean isChildren(Integer id) {
        QueryWrapper<Menu> wrapper = new QueryWrapper<>();
        wrapper.eq("parent_id", id);
        long count = baseMapper.selectCount(wrapper);
        return count > 0;
    }

    /**
     * 获取二级菜单
     *
     * @param permissions 权限
     * @return {@link List}<{@link Menu}>
     */
    private List<Menu> firsts(List<Menu> permissions){
        //1.一级菜单
        List<Menu> firsts=new ArrayList<>();
        for (Menu permission:permissions){
            if(permission.getParentId()==0){
                permission.setHasChildren(hasChild(permissions, permission));
                firsts.add(permission);
            }
        }

        //2.查询一级菜单下的二级菜单
        for(Menu first:firsts){
            List<Menu> children=new ArrayList<>();
            for(Menu p:permissions){
                if(first.getMenuId().equals(p.getParentId())){
                    p.setHasChildren(hasChild(permissions, p));
                    children.add(p);
                }
            }
            first.setChildren(children);
        }
        return firsts;
    }

    /**
     * 构建前端所需要树结构
     *
     * @param menus 菜单列表
     * @return 树结构列表
     */
    public List<Menu> buildMenuTree(List<Menu> menus) {
        List<Menu> returnList = new ArrayList<Menu>();
        List<Integer> tempList = new ArrayList<Integer>();
        for (Menu dept : menus) {
            tempList.add(dept.getMenuId());
        }
        for (Iterator<Menu> iterator = menus.iterator(); iterator.hasNext();) {
            Menu menu = (Menu) iterator.next();
            // 如果是顶级节点, 遍历该父节点的所有子节点
            if (!tempList.contains(menu.getParentId())) {
                recursionFn(menus, menu);
                returnList.add(menu);
            }
        }
        if (returnList.isEmpty()) {
            returnList = menus;
        }
        return returnList;
    }

    /**
     * 递归列表
     *
     * @param list
     * @param t
     */
    private void recursionFn(List<Menu> list, Menu t) {
        // 得到子节点列表
        List<Menu> childList = getChildList(list, t);
        t.setChildren(childList);
        for (Menu tChild : childList) {
            if (hasChild(list, tChild)) {
                recursionFn(list, tChild);
            }
        }
    }

    /**
     * 判断是否有子节点
     */
    private boolean hasChild(List<Menu> list, Menu t) {
        return getChildList(list, t).size() > 0;
    }

    /**
     * 得到子节点列表
     */
    private List<Menu> getChildList(List<Menu> list, Menu t) {
        List<Menu> tlist = new ArrayList<Menu>();
        Iterator<Menu> it = list.iterator();
        while (it.hasNext()) {
            Menu n = (Menu) it.next();
            if (n.getParentId().longValue() == t.getMenuId().longValue()) {
                tlist.add(n);
            }
        }
        return tlist;
    }
    
    
    
    
}